package com.atguigu.netty.simple;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelPipeline;
import io.netty.util.CharsetUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 说明
 * 1、自定义handler需要继承netty规定好某个HandlerAdapter
 */
public class NettyServerHandler extends ChannelInboundHandlerAdapter {

    private static Logger logger = LoggerFactory.getLogger(Thread.currentThread().getClass());

    /**
     * 读取客户端消息
     * ChannelHandlerContext ctx 上下文对象，含有管道pipeLine，通道，连接地址
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("server ctx=" + ctx);
        System.out.println("服务器读取线程" + Thread.currentThread().getName() + ", channel: " + ctx.channel());
        System.out.println("channel和pipeLine关系" + Thread.currentThread().getName());
        Channel channel = ctx.channel();
        ChannelPipeline pipeline = ctx.pipeline(); // 本质是双向链表，涉及出站入站

        //将msg转成byteBuffer
        // ByteBuf 是netty提供的，不是NIO的
        ByteBuf buf = (ByteBuf) msg;
        System.out.println("收到客户端发送消息：" + buf.toString(CharsetUtil.UTF_8));
        System.out.println("客户端地址：" + ctx.channel().remoteAddress());

        //比如这里有一个非常耗时的业务  -> 异步执行 ->  提交该channel对应的NIOEventLoop的taskQueue中
        // 解决方案1、 用户程序自定义普通任务
//        ctx.channel().eventLoop().execute(new Runnable() {
//            @Override
//            public void run() {
//                try {
//                    Thread.sleep(5 * 1000);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//                ctx.writeAndFlush(Unpooled.copiedBuffer("hello，客户端。。2222222222", CharsetUtil.UTF_8));
//            }
//        });
//       ctx.channel().eventLoop().execute(new Runnable() {
//            @Override
//            public void run() {
//                try {
//                    Thread.sleep(5 * 1000);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//                ctx.writeAndFlush(Unpooled.copiedBuffer("hello，客户端。。33333333333", CharsetUtil.UTF_8));
//            }
//        });
//        // 解决方案1、 用户自定义定时任务 -> 任务提交到scheduleTaskQueue
//        ctx.channel().eventLoop().schedule(new Runnable() {
//            @Override
//            public void run() {
//                try {
//                    Thread.sleep(5 * 1000);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//                ctx.writeAndFlush(Unpooled.copiedBuffer("hello，客户端。。44444444444", CharsetUtil.UTF_8));
//            }
//        }, 5, TimeUnit.SECONDS);


        System.out.println("go on.....");
    }

    /**
     * 数据读取完毕
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        // 将数据写入到缓存，并刷新
        // 通常对发送内容进行编码
        ctx.writeAndFlush(Unpooled.copiedBuffer("hello，客户端。。1111111111", CharsetUtil.UTF_8));
    }

    /**
     * 异常处理，通常关闭通道
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        logger.error("NettyServerHandler异常",cause);
        ctx.close();
    }
}
